package com.binarycube.webserver.config;

import java.io.File;
import java.util.Date;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.ExtendedBaseRules;
import org.apache.commons.digester.Rule;
import org.apache.log4j.Logger;

/**
 * Class to load the serverconfig.xml file
 * @author chris
 *
 */
public class ConfigLoader {
	static Logger log = Logger.getLogger(ConfigLoader.class.getName());
	
	public static String CONFIG_FILE = "etc/serverconfig.xml"; 
	public static String DATA_CONFIG_FILE = "etc/data.xml"; 
	
	public static ServerConfig loadServerConfig(){
		return loadServerConfig(new File(CONFIG_FILE));
	
	}
	
	public static ServerConfig loadServerConfig(File f) {
		
		//Then configure the Digester
	    Digester digester = new Digester();
	    digester.setValidating( false );
	    digester.setRules(new ExtendedBaseRules());
	    
	    //The main object tag
	    digester.addObjectCreate( "server", ServerConfig.class );
	    digester.addSetProperties("server" , "name", "name");
	    digester.addSetProperties("server" , "port", "port");
	    digester.addSetProperties("server" , "serverRoot", "serverRoot");
	    digester.addSetProperties("server" , "pageBase", "pageBase");
	    digester.addSetProperties("server" , "scriptBase", "scriptBase");
	    digester.addSetProperties("server" , "welcome", "welcome");
	    digester.addSetProperties("server" , "loginURL", "loginURL");
	    
	    //Session Manager
	    digester.addObjectCreate("server/sessionManager", SessionManagerConfig.class);
	    digester.addSetProperties("server/sessionManager" , "class", "clazz");
	    digester.addRule("server/sessionManager/?", new Rule() {
            @Override public void body(String nspace, String name, String text) {
                ((SessionManagerConfig)getDigester().peek()).addProperty(name, text);
            }
        });
	    digester.addSetNext("server/sessionManager", "setSessionManager");
	    
	    
	    //Authentication 
	    digester.addObjectCreate("server/authenticator", AuthenticatorConfig.class);
	    digester.addSetProperties("server/authenticator" , "class", "clazz");
	    digester.addSetProperties("server/authenticator" , "usernameField", "usernameField");
	    digester.addSetProperties("server/authenticator" , "passwordField", "passwordField");
		      
	    digester.addRule("server/authenticator/?", new Rule() {
            @Override public void body(String nspace, String name, String text) {
                ((AuthenticatorConfig)getDigester().peek()).addProperty(name, text);
            }
        });
	    digester.addSetNext("server/authenticator", "setAuthenticator");
	    
	    
	    //Pages
	    digester.addObjectCreate("server/pages/page", PageConfig.class);
	    digester.addSetProperties("server/pages/page" , "name", "name");
	    digester.addSetProperties("server/pages/page" , "src", "source");
	    digester.addSetProperties("server/pages/page" , "visibility", "visibility");
	    digester.addSetNext("server/pages/page", "addPage");
	    
	    
	   //Data Sources
	    digester.addObjectCreate("server/data/datasource", DatasourceConfig.class);
	    digester.addSetProperties("server/data/datasource" , "name", "name");
	    digester.addSetProperties("server/data/datasource" , "class", "clazz");
	    digester.addRule("server/data/datasource/?", new Rule() {
            @Override public void body(String nspace, String name, String text) {
                ((DatasourceConfig)getDigester().peek()).addProperty(name, text);
            }
        });
	    digester.addSetNext("server/data/datasource", "addDatasource");
	   
	    
	    //Scripts
	    digester.addObjectCreate("server/scripts/script", ScriptConfig.class);
	    digester.addSetProperties("server/scripts/script" , "name", "name");
	    digester.addSetProperties("server/scripts/script" , "src", "source");
	    digester.addSetProperties("server/scripts/script" , "visibility", "visibility");
	    digester.addRule("server/scripts/script/?", new Rule() {
            @Override public void body(String nspace, String name, String text) {
                ((ScriptConfig)getDigester().peek()).addProperty(name, text);
            }
        });
	    digester.addSetNext("server/scripts/script", "addScript");
	    
	    
	    
	    ServerConfig tmp = null;
		try {
			tmp = (ServerConfig)digester.parse(f);
			tmp.setLoadedTS(new Date());
			return tmp;
		} catch (Exception e) {
			log.error("Error parsing XML", e);
		}
		return null;
	}
	
	public static DataManagerConfig loadDataConfig(){
		return loadDataConfig(new File(DATA_CONFIG_FILE));
	
	}
	
	public static DataManagerConfig loadDataConfig(File f) {
		
		//Then configure the Digester
	    Digester digester = new Digester();
	    digester.setValidating( false );
	    digester.setRules(new ExtendedBaseRules());
	    
	    //The main object tag
	    digester.addObjectCreate( "data", DataManagerConfig.class );
	
	    
	   //Data Sources
	    digester.addObjectCreate("data/datasource", DatasourceConfig.class);
	    digester.addSetProperties("data/datasource" , "name", "name");
	    digester.addSetProperties("data/datasource" , "class", "clazz");
	    
	    digester.addRule("data/datasource/config/?", new Rule() {
            @Override public void body(String nspace, String name, String text) {
                ((DatasourceConfig)getDigester().peek()).addProperty(name, text);
            }
        });
	    digester.addSetNext("data/datasource", "addDatasource");
	   
	    digester.addObjectCreate( "data/datasource/parameters/parameter", ParameterConfig.class );
	    digester.addSetProperties("data/datasource/parameters/parameter" , "name", "name");
	    digester.addSetProperties("data/datasource/parameters/parameter" , "default", "default");
	    
	    digester.addSetNext("data/datasource/parameters/parameter", "addParameter");
	    
	    
	    DataManagerConfig tmp = null;
		try {
			tmp = (DataManagerConfig)digester.parse(f);
			return tmp;
		} catch (Exception e) {
			log.error("Error parsing XML", e);
		}
		return null;
	}
	
	
	
	

}
